function DroidBuff(type, timeout) {
	this.timeApplied = 0;
	this.type = type;
	this.timeout = timeout;
};

DroidBuff.EXPLODER = 0;
DroidBuff.FLOATER = 1;
DroidBuff.CLIMBER = 2;

DroidBuff.EXPLODER_TIMEOUT = 100;

DroidBuff.prototype.step = function() {
	this.timeApplied++;
};

DroidBuff.prototype.timeRemaining = function() {
	return this.timeout - this.timeApplied;
};

function Droid(x, y, xvel, yvel, lastX, lastY, buffs, world, sprite) {

	this.selection = new DroidSelection();

	this.x = x;
	this.y = y;
	this.xvel = xvel;
	this.yvel = yvel;
	this.xaccel = 0;
	this.yaccel = 0.4;
	this.width = 17;
	this.height = 28;

	this.friction = 0;

	this.lastx = lastX;
	this.lasty = lastY;

	this.nextDroid = this;

	this.buffs = buffs;

	this.changedDirection;
	this.canChangeDirection = true;

	this.selected = false;

	this.sprite = sprite || new Sprite();
	this.world = world;
	this.terrainManager = world.terrainManager;

	this.clear = function(ctx) {
		this.selection.clear(ctx);
	};

	this.drawTimer = function(ctx) {
		for ( var i = 0; i < this.buffs.length; i++) {
			if (this.buffs[i].timeRemaining() >= 0) {
				ctx.fillStyle = '#ca4939';
				ctx.textBaseline = 'bottom';
				ctx.textAlign = "center";
				ctx.font = 'bold 10px monospace';
				ctx.fillText(this.buffs[i].timeRemaining(), this.selection.xLeft + (this.selection.WIDTH / 2), this.selection.yTop);
			}
		}
	};

	this.draw = function(ctx, canvasWidth, canvasHeight, step) {
		this.sprite.drawImage(step, ctx, this.x, this.y);
		this.selection.setPosition(this.x, this.y, this.width, this.height);

		if (DEBUG_COLLISIONS) {
			ctx.strokeStyle = "rgba(0,200,200,0.5)";
			ctx.strokeRect(this.x, this.y, this.width, this.height);
		}
	};

	this.drawSelection = function(ctx) {
		if (this.selected) {
			this.selection.draw(ctx);
		}

		this.drawTimer(ctx);
	};

	this.drill = function() {
		this.sprite.drill();
		this.xvel = 0;
	};

	this.stop = function() {
		this.sprite.stopMovement();
		this.xvel = 0;
	};

	this.goLeft = function() {
		this.sprite.goLeft();
	};

	this.goRight = function() {
		this.sprite.goRight();
	};

	this.block = function() {
		this.sprite.block();
		this.xvel = 0;
	};

	this.jump = function() {
		if (this.yvel == 0)
			this.yvel = -4;
	};

	this.aboutFace = function() {
		if (this.changedDirection || !this.canChangeDirection)
			return;
		this.changedDirection = true;
		this.xvel *= -1;
		if (this.xvel > 0) {
			this.sprite.goRight();
		} else {
			this.sprite.goLeft();
		}
	};

	this.death = function() {
		this.xvel = 0;
		// have animation for death here

	};

	this.step = function() {
		if (this.xvel != 0)
			this.xaccel = this.xvel / Math.abs(this.xvel) * this.friction * -1;
		this.xvel += this.xaccel;
		this.yvel += this.yaccel;
		this.x += this.xvel;
		this.y += this.yvel;

		this.breakDownBlocks();
		this.beforeCollisions();
		this.doCollisions();
		this.afterCollisions();
		this.updateBuffs();

		this.lastx = this.x;
		this.lasty = this.y;
	};

	this.destroyBlocks = function() {
		var blocks = this.terrainManager.getTerrain(this.x, this.y, this.width, this.height);
		for ( var i = 0; i < blocks.length; i++) {
			var currentBlock = blocks[i];
			currentBlock.health -= 5;
			if (currentBlock.health <= 0) {
				this.terrainManager.destroyTerrain(currentBlock);
			}
		}
	};

	this.overlapsWith = function(currentBlock) {
		if (currentBlock.destroyed)
			return false;
		return overlaps(this.x, this.y, this.width, this.height, currentBlock.x, currentBlock.y, currentBlock.width, currentBlock.height);
	};

	this.getSurroundingBlocks = function(left, right, above, below) {
		var regionX = this.x - left;
		var regionY = this.y - above;
		var regionWidth = this.width + left + right;
		var regionHeight = this.height + above + below;
		return this.terrainManager.getTerrain(regionX, regionY, regionWidth, regionHeight);
	};

	this.breakDownBlocksMore = function() {
		var blocks = this.terrainManager.getTerrain(this.x, this.y, this.width, this.height);
		for ( var i = 0; i < blocks.length; i++) {
			var currentBlock = blocks[i];
			currentBlock.health -= 5;
			if (currentBlock.health <= 0) {
				this.terrainManager.breakDownMore(currentBlock);
			}
		}
	};

	this.breakDownBlocks = function() {
		var blocks = this.terrainManager.getTerrain(this.x, this.y, this.width, this.height);
		for ( var i = 0; i < blocks.length; i++) {
			var currentBlock = blocks[i];
			currentBlock.health -= 5;
		}
	};

	this.doCollisions = function() {
		this.changedDirection = false;
		// if (this.selected) {
		// console.log("do_collisions");
		// }
		var blocks = this.terrainManager.getTerrain(this.x, this.y, this.width, this.height);
		for ( var i = 0; i < blocks.length; i++) {
			var currentBlock = blocks[i];
			this.doCollision(currentBlock);
		}
	};

	this.doCollision = function(currentBlock) {
		// if (this.selected) {
		// console.log("do_collision");
		// }
		if (this.overlapsWith(currentBlock)) {
			// if (this.selected) {
			// console.log("collide");
			// }
			if (this.lastx + this.width <= currentBlock.x && this.x + this.width > currentBlock.x) {
				// if (this.selected) {
				// console.log("a");
				// }
				var success = this.collideIncline(currentBlock);
				if (!success) 
					this.collideRight(currentBlock);
			}

			if (this.lastx >= currentBlock.x + currentBlock.width && this.x < currentBlock.x + currentBlock.width) {
				// if (this.selected) {
				// console.log("b");
				// }
				var success = this.collideIncline(currentBlock);
				if (!success) 
					this.collideLeft(currentBlock);
			}

			if (this.lasty + this.height <= currentBlock.y && this.y + this.height > currentBlock.y) {
				// if (this.selected) {
				// console.log("c");
				// }
				this.collideBelow(currentBlock);
			}

			if (this.lasty >= currentBlock.y + currentBlock.height && this.y < currentBlock.y + currentBlock.height) {
				// if (this.selected) {
				// console.log("d");
				// }
				this.collideAbove(currentBlock);
			}
		}
		if (this.overlapsWith(currentBlock) && currentBlock.forceOutside) {
			rightDist = Math.abs(this.x - (currentBlock.x + currentBlock.width));
			leftDist = Math.abs(this.x - (currentBlock.x - this.dwidth));
			upDist = Math.abs(this.y - (currentBlock.y - this.height));
			downDist = Math.abs(this.y - (currentBlock.y + currentBlock.height));
			minDist = Math.min(rightDist, leftDist, upDist, downDist);
			if (minDist == rightDist) {
				this.x = currentBlock.x + currentBlock.width;
			} else if (minDist == leftDist) {
				this.x - this.width;
			} else if (minDist == upDist) {
				this.y = currentBlock.y - this.height;
			} else {
				this.y = currentBlock.y + currentBlock.height;
			}
		}
	};

	// this.doActions = function(terrainManager) {
	// if (this.sprite.animation.name == "drill") {
	// this.breakDownBlocksMore(terrainManager);
	// this.destroyBlocks(terrainManager);
	// }
	// };

	// this.doAction = function(action) {
	// this.drill();
	// };
}

Droid.prototype.afterCollisions = function() {
};

Droid.prototype.beforeCollisions = function() {
};

Droid.prototype.changeDroidType = function(droidType) {
	return this.setTransform(droidType);
};

Droid.prototype.isLegalTransform = function(transform) {
	return true;
};

Droid.prototype.setTransform = function(transform) {
	if (this.nextDroid != this)
		return false;
	if (this.isLegalTransform(transform)) {
		this.nextDroid = new transform(this.x, this.y, this.xvel, this.yvel, this.lastx, this.lasty, this.buffs, this.world, this.sprite);
		return true;
	}
	return false;
};

Droid.prototype.transform = function() {
	if (this.nextDroid != this)
		this.cleanup();
	return this.nextDroid;
};

Droid.prototype.cleanup = function() {
};

Droid.prototype.tryMove = function(x, y) {
	var lastX = this.x;
	var lastY = this.y;
	this.x = x;
	this.y = y;
	var surrounding = this.getSurroundingBlocks(0, 0, 0, 0);
	var touching = false;
	for (var i = 0; i < surrounding.length; i++) {
		if (this.overlapsWith(surrounding[i])) {
			touching = true;
		}
	}
	this.x = lastX;
	this.y = lastY;
	return !touching;
};

Droid.prototype.collideIncline = function(currentBlock) {
	if (Math.abs(this.y + this.height - currentBlock.y) >= 4)
		return false;
	if (this.tryMove(this.x, currentBlock.y - this.height)) {
		this.y = currentBlock.y - this.height;
		this.yvel = 0;
		return true;
	}
	return false;
};

Droid.prototype.collideRight = function(currentBlock) {
	this.aboutFace();
	this.x = currentBlock.x - this.width;
};

Droid.prototype.collideLeft = function(currentBlock) {
	this.aboutFace();
	this.x = currentBlock.x + currentBlock.width;
};

Droid.prototype.collideBelow = function(currentBlock) {
	this.y = currentBlock.y - this.height;
	this.yvel = 0;
};

Droid.prototype.collideAbove = function(currentBlock) {
	this.yvel *= -1;
	this.y = currentBlock.y + currentBlock.height;
};

Droid.prototype.addBuff = function(buff) {
	for ( var i = 0; i < this.buffs.length; i++) {
		if (this.buffs[i].type == buff.type)
			return false;
	}
	this.buffs.push(buff);
	return true;
};

Droid.prototype.updateBuffs = function() {
	for ( var i = 0; i < this.buffs.length; i++) {
		this.buffs[i].step();
	}
	if (this.hasBuff(DroidBuff.EXPLODER) && buff.timeRemaining() <= 0) {
		this.changeDroidType(Exploder);
	}
};

Droid.prototype.hasBuff = function(buff) {
	for ( var i = 0; i < this.buffs.length; i++) {
		if (buff == this.buffs[i].type) {
			return true;
		}
	}
	return false;
};

Droid.prototype.isSelectable = function() {
	return true;
};